// Copyright 2011, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dfp.axis.other;

import com.google.api.ads.dfp.lib.client.DfpSession;
import com.google.api.ads.dfp.lib.client.DfpSession.Environment;
import com.google.api.ads.dfp.lib.factory.DfpServices;
import com.google.api.ads.dfp.axis.v201111.Network;
import com.google.api.ads.dfp.axis.v201111.NetworkServiceInterface;
import com.google.api.client.auth.oauth.OAuthCredentialsResponse;
import com.google.api.client.auth.oauth.OAuthHmacSigner;
import com.google.api.client.auth.oauth.OAuthParameters;
import com.google.api.client.googleapis.auth.oauth.GoogleOAuthAuthorizeTemporaryTokenUrl;
import com.google.api.client.googleapis.auth.oauth.GoogleOAuthGetAccessToken;
import com.google.api.client.googleapis.auth.oauth.GoogleOAuthGetTemporaryToken;
import com.google.api.client.http.javanet.NetHttpTransport;

import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * This example demonstrates how to authenticate using OAuth.  This example
 * is meant to be run from the command line and requires user input.
 *
 * @author Adam Rogal
 */
public class OAuthExample {

  @SuppressWarnings("unused")
  private final static String PRODUCTION_SCOPE = "https://www.google.com/apis/ads/publisher";
  private final static String SANDBOX_SCOPE = "https://sandbox.google.com/apis/ads/publisher";

  public static void main(String[] args) throws Exception {
    // Set the OAuth consumer key and secret. Anonymous values can be used for
    // testing, and real values can be obtained by registering your application:
    // http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html
    String consumerKey = "anonymous";
    String consumerSecret = "anonymous";

    // Create the HMAC signer.
    OAuthHmacSigner signer = new OAuthHmacSigner();
    signer.clientSharedSecret = consumerSecret;

    // Construct the client to get the temporary token.
    GoogleOAuthGetTemporaryToken oAuthGetTemporaryToken =
        new GoogleOAuthGetTemporaryToken();

    oAuthGetTemporaryToken.consumerKey = consumerKey;
    // Set this to PRODUCTION_SCOPE if production is used instead of sandbox.
    oAuthGetTemporaryToken.scope = PRODUCTION_SCOPE;
    oAuthGetTemporaryToken.signer = signer;
    oAuthGetTemporaryToken.displayName = "INSERT_DISPLAY_NAME_HERE";
    oAuthGetTemporaryToken.transport = new NetHttpTransport();

    // Request a new OAuth token. Web applications should pass in a callback
    // URL to redirect the user to after authorizing the token using
    // oAuthGetTemporaryToken.build(). "oob" is used in this case to display
    // the verification code on the screen.
    oAuthGetTemporaryToken.callback = "oob";
    OAuthCredentialsResponse oAuthCredentialResponse = oAuthGetTemporaryToken.execute();

    // Construct the URL to authorize a temporary token.
    GoogleOAuthAuthorizeTemporaryTokenUrl oAuthAuthorizeTemporaryTokenUrl =
        new GoogleOAuthAuthorizeTemporaryTokenUrl();
    String temporaryToken = oAuthCredentialResponse.token;
    oAuthAuthorizeTemporaryTokenUrl.temporaryToken = temporaryToken;

    // Set the token shared secret on the signer.
    signer.tokenSharedSecret = oAuthCredentialResponse.tokenSecret;

    // In a web application, you would redirect the user to the authorization
    // URL and after approving the token they would be redirected back to the
    // callback URL, with the URL parameter "oauth_verifier" added. For
    // desktop or server applications, spawn a browser to the URL and then
    // have the user enter the verification code that is displayed.
    System.out.printf("Log into your account with the following URL:\n%s\n",
        oAuthAuthorizeTemporaryTokenUrl.build());
    System.out
        .println("After approving the token, enter the verification code (oauth_verifier):");
    String verifier = new BufferedReader(new InputStreamReader(System.in)).readLine().trim();

    // Construct the upgrade the authorized token.
    GoogleOAuthGetAccessToken oAuthGetAccessToken = new GoogleOAuthGetAccessToken();
    oAuthGetAccessToken.consumerKey = consumerKey;
    oAuthGetAccessToken.temporaryToken = temporaryToken;
    oAuthGetAccessToken.verifier = verifier;
    oAuthGetAccessToken.signer = oAuthGetTemporaryToken.signer;
    oAuthGetAccessToken.transport = new NetHttpTransport();

    // Upgrade the authorized token.
    oAuthCredentialResponse = oAuthGetAccessToken.execute();

    // Set the token secret.
    signer.tokenSharedSecret = oAuthCredentialResponse.tokenSecret;

    // Build OAuthParameters.
    OAuthParameters oAuthParameters = new OAuthParameters();
    oAuthParameters.version = "1.0a";
    oAuthParameters.token = oAuthCredentialResponse.token;
    oAuthParameters.consumerKey = consumerKey;
    oAuthParameters.signer = signer;

    DfpSession session = new DfpSession.Builder().fromFile()
        .withOAuthParameters(oAuthParameters)
        .withEnvironment(Environment.PRODUCTION).build();

    // Get the NetworkService.
    NetworkServiceInterface networkService =
        new DfpServices().get(session, NetworkServiceInterface.class);

    // Get all networks that you have access to with the current login
    // credentials.
    Network[] networks = networkService.getAllNetworks();

    int i = 0;
    for (Network network : networks) {
      System.out.println(i + ") Network with network code \"" + network.getNetworkCode()
          + "\" and display name \"" + network.getDisplayName() + "\" was found.");
      i++;
    }
    System.out.println("Number of networks found: " + i);
  }
}
